package net.sf.odinms.exttools.doclet.pages;

import java.io.IOException;
import com.sun.javadoc.PackageDoc;
import com.sun.tools.doclets.internal.toolkit.util.ClassTree;
import com.sun.tools.doclets.internal.toolkit.util.DirectoryManager;
import net.sf.odinms.exttools.doclet.Doclet;

/**
 * Creates "{packagepath}/package-tree.html" showing a package's hierarchy.
 */
public final class PackageTree extends AbstractTree {
	
	/**
	 * The previous package name in the alpha-order list.
	 */
	private PackageDoc prev;
	
	/**
	 * The next package name in the alpha-order list.
	 */
	private PackageDoc next;
	
	/**
	 * The name of the package for which the hierarchy is to be generated.
	 */
	private String pkgName;
	
	/**
	 * Constructs a PackageTree object and uses it to create the package tree.
	 * 
	 * @param pkg Package for which tree file is to be generated.
	 * @param prev Previous package in the alpha-ordered list.
	 * @param next Next package in the alpha-ordered list.
	 */
	public static void generatePackageTree(PackageDoc pkg, PackageDoc prev,
			PackageDoc next) {
		String filename = "package-tree" + CONF.ext;
		String pathToFile = DirectoryManager.getDirectoryPath(pkg);
		try {
			new PackageTree(filename, pathToFile, pkg, prev, next);
		}
		catch (IOException exc) {
			throw Doclet.exception(exc, pathToFile + SLASH + filename);
		}
	}
	
	/**
	 * Initialize filename and page type for tree of elements of this package.
	 * 
	 * @param filename The desired name of the file (with extension).
	 * @param pathToFile The path from the document root to this file.
	 * @param pkg Package for which tree file is to be generated.
	 * @param prev The previous package in the alpha-ordered list.
	 * @param next The following package in the alpha-ordered list.
	 * @throws IOException If {@link java.io.FileOutputStream} creation fails.
	 */
	private PackageTree(String filename, String pathToFile, PackageDoc pkg,
			PackageDoc prev, PackageDoc next) throws IOException {
		super(filename, pathToFile);
		CONF.classTree =
				new ClassTree(CONF.classDocCatalog.allClasses(pkg), CONF);
		pageType = PageType.PACKAGE_TREE;
		CONF.currentPkg = pkg;
		pkgName = pkg.name();
		this.prev = prev;
		this.next = next;
		
		// Start generating page
		windowTitle =
				(CONF.windowtitle.length() > 0) ? CONF.windowtitle : pkg.name()
						+ " " + CONF.propertyText("Tree");
		
		printXhtmlHeader();
		
		printEntityCaption(pkg, "Hierarchy for Package");
		
		// Do nothing if only unnamed package is used
		if ((packages.length != 1 || packages[0].name().length() > 0)
				&& !classesOnly) {
			println(openDivWithID("Overview"));
			println(open("dl"));
			println(open("dt") + CONF.propertyText("Package_Hierarchies")
					+ close("dt"));
			println(open("dd")
					+ listItem(linkToLabelHref("All Packages", pathToDocRoot
							+ "overview-tree" + CONF.ext)) + close("dd"));
			println(close("dl"));
			println(close("div") + getComment("#Overview"));
		}
		
		printMemberSubgroups();
		
		printXhtmlFooter();
		this.close();
	}
	
	/** Link "Package" to the summary for the current package. */
	protected void navLinkPackage() {
		println(listItem(linkToLabelHrefTitle(PACKAGE, "package-summary"
				+ CONF.ext, CONF.propertyText("navtitle.Package", pkgName))));
	}
	
	/** Link "Use" to the use of the current package. */
	protected void navLinkUse() {
		println(listItem(linkToLabelHrefTitle(USE, "package-use" + CONF.ext,
				CONF.propertyText("navtitle.Use", pkgName))));
	}
	
	/** Print links to previous and next packages, or static label if none. */
	protected void navPreviousNext() {
		println(openULWithID("PreviousNext"));
		println(listItem(linkToLabelHref(PREV_PKG, hrefToDoc(prev)
				+ "package-tree" + CONF.ext))
				+ listItemLast(linkToLabelHref(NEXT_PKG, hrefToDoc(next)
						+ "package-tree" + CONF.ext)));
		println(close("ul"));
	}
	
}
